<script setup>
import { computed, ref } from 'vue'
import MemoryManager from '@/business/MemoryManager' // 引入 MemoryManager 类

// 初始化内存管理器
const totalMemory = ref(100)
const memoryManager = ref(new MemoryManager(totalMemory.value))
const newProcessSize = ref(10)
const allocationMethod = ref('firstFit')
const allocatedProcesses = computed(
  () => memoryManager.value.allocatedProcesses
)
// const processCounter = ref(memoryManager.processCounter)
const memoryBlocks = computed(() => memoryManager.value.memoryBlocks)
const showErrorModal = ref(false)
const message = ref('')

// 分配进程
const allocateProcess = () => {
  if (newProcessSize.value <= 0) {
    showErrorModal.value = true
    message.value = '请输入有效的进程内存大小'
    return
  }

  let result = -1
  switch (allocationMethod.value) {
    case 'firstFit':
      result = memoryManager.value.firstFitAllocate(newProcessSize.value)
      break
    case 'bestFit':
      result = memoryManager.value.bestFitAllocate(newProcessSize.value)
      break
    case 'worstFit':
      result = memoryManager.value.worstFitAllocate(newProcessSize.value)
      break
  }

  if (result === -1) {
    showErrorModal.value = true
    message.value = '内存分配失败，没有足够的空闲空间'
  }
}

// 释放进程
const releaseProcess = (processId) => {
  memoryManager.value.releaseProcess(processId)
  allocatedProcesses.value = memoryManager.value.allocatedProcesses
  memoryBlocks.value = memoryManager.value.memoryBlocks
}

// 关闭错误弹窗
const closeErrorModal = () => {
  showErrorModal.value = false
}

// 清空内存区
const clearMemory = () => {
  memoryManager.value.memoryBlocks.forEach((block) => {
    block.processId = null
  })
  memoryManager.value.allocatedProcesses = []

  memoryManager.value.mergeAdjacentFreeBlocks()
  memoryManager.value.processCounter = 1
}

// 更新内存区
const updateMemory = () => {
  console.log('updateMemory')
  memoryManager.value = new MemoryManager(totalMemory.value)
}
</script>

<template>
  <div class="memory-management-container">
    <h2>动态内存管理模拟器</h2>
    <div class="config-section">
      <div class="memory-config">
        <label>总内存大小 (MB):</label>
        <input
          type="number"
          v-model="totalMemory"
          min="100"
          max="10000"
          @input.prevent="updateMemory"
        />
      </div>
      <div class="allocation-method">
        <label>分配算法:</label>
        <select v-model="allocationMethod">
          <option value="firstFit">最先适应算法</option>
          <option value="bestFit">最佳适应算法</option>
          <option value="worstFit">最坏适应算法</option>
        </select>
      </div>
    </div>

    <div class="process-input">
      <label>进程大小 (MB):</label>
      <input
        type="text"
        v-model.number="newProcessSize"
        placeholder="输入进程大小 (MB)"
        @keydown.enter="allocateProcess"
      />
      <button class="allocate-btn" @click="allocateProcess">分配进程</button>
      <button class="allocate-btn" @click="clearMemory">清空内存区</button>
    </div>

    <div class="memory-visualization">
      <div
        class="memory-block"
        v-for="(block, index) in memoryBlocks"
        :key="index"
        :style="{
          width: `${(block.size / totalMemory) * 100}%`,
          backgroundColor: block.processId
            ? memoryManager.getProcessColor(block.processId)
            : '#f0f0f0',
          borderRadius: '5px'
        }"
      >
        <span v-if="block.processId">
          进程 {{ block.processId }} <br />
          {{ block.size }} MB
        </span>
        <span v-else>空闲 {{ block.size }} MB</span>
      </div>
    </div>

    <div class="process-list">
      <h3>已分配的进程</h3>
      <table>
        <thead>
          <tr>
            <th>进程ID</th>
            <th>内存大小</th>
            <th>起始地址</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="process in allocatedProcesses" :key="process.id">
            <td>{{ process.id }}</td>
            <td>{{ process.size }} MB</td>
            <td>{{ process.startAddress }} MB</td>
            <td>
              <button @click="releaseProcess(process.id)" class="release-btn">
                释放
              </button>
            </td>
          </tr>
          <tr v-if="allocatedProcesses.length === 0">
            <td colspan="4">暂无已分配的进程</td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 弹出框 -->
    <div v-if="showErrorModal" class="modal-overlay" @click="closeErrorModal">
      <div class="modal-content" @click.stop>
        <h3>内存分配失败</h3>
        <p>{{ message }}</p>
        <button @click="closeErrorModal">关闭</button>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.memory-management-container {
  max-width: 90rem;
  margin: 1rem auto;
  font-family: Arial, sans-serif;
}

h2 {
  text-align: center;
  margin-bottom: 2rem;
  color: #333;
  font-size: 1.8rem;
}

.config-section {
  display: flex;
  justify-content: space-between;
  margin-bottom: 2rem;
  font-size: 1.4rem;
}

.memory-config,
.allocation-method {
  display: flex;
  align-items: center;
  gap: 1rem;
}

input,
select,
button {
  padding: 8px 12px;
  border: 1px solid #ccc;
  border-radius: 5px;
}

input:focus,
select:focus,
button:focus {
  outline: none;
  border-color: #007bff;
}

.process-input {
  font-size: 1.4rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.allocate-btn {
  background-color: #007bff;
  color: #fff;
  border: none;
  cursor: pointer;
  transition: background-color 0.3s ease;
  margin-left: 2rem;
}

.allocate-btn:hover {
  background-color: #0056b3;
}

.release-btn {
  background-color: #dc3545;
  color: #fff;
  border: none;
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.release-btn:hover {
  background-color: #a71d2a;
}

.memory-visualization {
  display: flex;
  width: 100%;
  height: 60px;
  border: 1px solid #ccc;
  border-radius: 5px;
  overflow: hidden;
  margin-bottom: 4rem;
  margin-top: 2rem;
}

.memory-block {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-right: 1px solid #ddd;
  color: #333;
  font-size: 1.4rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;

  span {
    word-wrap: break-word;
    white-space: normal;
  }
}

.memory-block:last-child {
  border-right: none;
}

.process-list {
  font-size: 1.4rem;
}

table {
  width: 100%;
  border-collapse: collapse;
  text-align: center;
}

th,
td {
  border: 1px solid #ddd;
  padding: 10px;
}

th {
  background-color: #f8f9fa;
}

td button {
  padding: 5px 10px;
  font-size: 14px;
}

tr:nth-child(even) {
  background-color: #f9f9f9;
}

tr:hover {
  background-color: #f1f1f1;
}

td[colspan='4'] {
  text-align: center;
  color: #666;
  font-style: italic;
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background-color: #fff;
  padding: 20px;
  border-radius: 10px;
  text-align: center;
  max-width: 400px;
  width: 100%;
  font-size: 1.2rem;
}

.modal-content button {
  margin-top: 15px;
  padding: 8px 16px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.modal-content button:hover {
  background-color: #0056b3;
}
</style>
